#include "game.h"

game *game::instance = NULL;

game* game::getInstance(){
	if(!instance){
		instance = new game();
	}
	return instance;
}

game::game(){
	vcol=0;
	hcol=0;
	count=0;
	g_counter=0;
	g_enemySpawnTrigger=0;
	myLevelOneCount = 0;
	myLevelTwoCount = 0;
	myLevelThreeCount = 0;
	myLevelFourCount = 0;
}

game::~game(){
	//delete player;
	player=NULL;
}


void game::startGame(){
	g_currentLevel=1;
	cutScene(1);
	startLevel(1);
	//AKS HACK
	//Restart level to avoid a bug with power up sprite.
	//No clue why the bug is there or why this fixes it.
	//resetLevel();
}

void game::startLevel(int level){
	
	player= Player::getInstance();
	Camera= camera::getInstance();
	clearLevel();
	

	if(level == 1){
		g_currentLevel=1;
		player->setPos(0.0,208.0);
		Map.DisplayMap(level1Pal,level1PalLen,level1Tiles,level1TilesLen,level1Map,level1MapLen);
		Map.setMap((u16*)level1Map);
		Map.loadCurrentScreen(Camera->getPos());
		Map.loadMetaData(g_currentLevel);
		Map.displayBackground(SummerBackgroundBitmap,SummerBackgroundBitmapLen);
		Map.displaySubScreen(phoneBackgroundBitmap,phoneBackgroundBitmapLen);
		createPowerups(g_currentLevel);
		createEnemies(g_currentLevel);
		if(myLevelOneCount == 0){
		myLevelOneCount++;
		resetLevel();
		}
	}else if(level == 2){
		g_currentLevel=2;
		player->setPos(0.0,208.0);
		Map.DisplayMap(level2Pal,level2PalLen,level2Tiles,level2TilesLen,level2Map,level2MapLen);
		Map.setMap((u16*)level2Map);
		Map.loadCurrentScreen(Camera->getPos());
		Map.loadMetaData(g_currentLevel);
		Map.displayBackground(FallBackgroundBitmap,FallBackgroundBitmapLen);
		Map.displaySubScreen(phoneBackgroundBitmap,phoneBackgroundBitmapLen);
		createPowerups(g_currentLevel);
		createEnemies(g_currentLevel);
		if(myLevelTwoCount == 0){
		myLevelTwoCount++;
		resetLevel();
		}
	}else if(level == 3){
		g_currentLevel=3;
		player->setPos(0.0,208.0);
		Map.DisplayMap(level3Pal,level3PalLen,level3Tiles,level3TilesLen,level3Map,level3MapLen);
		Map.setMap((u16*)level3Map);
		Map.loadCurrentScreen(Camera->getPos());
		Map.loadMetaData(g_currentLevel);
		Map.displayBackground(WinterBackgroundBitmap,WinterBackgroundBitmapLen);
		Map.displaySubScreen(phoneBackgroundBitmap,phoneBackgroundBitmapLen);
		createPowerups(g_currentLevel);
		createEnemies(g_currentLevel);
		if(myLevelThreeCount == 0){
		myLevelThreeCount++;
		resetLevel();
		}
	}else{
		g_currentLevel=4;
		player->setPos(0.0,208.0);
		Map.DisplayMap(level4Pal,level4PalLen,level4Tiles,level4TilesLen,level4Map,level4MapLen);
		Map.setMap((u16*)level4Map);
		Map.loadCurrentScreen(Camera->getPos());
		Map.loadMetaData(g_currentLevel);
		Map.displayBackground(SpringBackgroundBitmap,SpringBackgroundBitmapLen);
		Map.displaySubScreen(phoneBackgroundBitmap,phoneBackgroundBitmapLen);
		createPowerups(g_currentLevel);
		createEnemies(g_currentLevel);
		if(myLevelFourCount == 0){
		myLevelFourCount++;
		resetLevel();
		}

	}
}

void game::update(){
	if(player->isDead()){
		deadLeadsToReset();
	}
	g_counter++;
	player->printInfo(Camera->getPos());
	player->update();
	
	detectOffscreenWeapons();
			
	for (int i = 0; i < projectiles.size(); i++) {
		projectiles[i]->updateWeapon();
	//	printf("%f\n",(float)projectiles[i]->getPos().x);
	}
	
	//printf("%i\n",powerups.size());
	vector<powerup*>::iterator iterPowerup;
	for(iterPowerup = powerups.begin(); iterPowerup != powerups.end(); iterPowerup++){
		(*iterPowerup)->update();
		//printf("%f %f\n",(float)iterPowerup->getPos().x,(float)iterPowerup->getPos().y);
	}
	//spawnEnemy();

	detectCollision();

	moveScreen();

	moveEnemy();
	Map.updateMap(Camera->getPos());
	

	detectKeys();
	//paused=1;
	//pauseGame();

}

void game::detectCollision(){
	//NO TOUCHIES || youDie();
	hcol=0;
	vcol=0;
	int anyCollide=0;
	bool icy=false;
	t2DVector screenPos = Camera->getPos();
	int screenPosX = screenPos.x/(Fixed)tileSize;
	int screenPosY = screenPos.y/(Fixed)tileSize;
	int endScreenPosX = screenPosX + 16;
	int endScreenPosY = screenPosY + 12;

	for(int x=screenPosX;x<endScreenPosX;x++){
		for(int y=screenPosY;y<endScreenPosY;y++){
			if(Map.returnCollideable(x,y) >= 1 && Map.returnCollideable(x,y) <= 3){
				BoundingBox targetTile;
                targetTile.top = y*16;
                targetTile.left = x*16;
                targetTile.right = (x+1)*16;
                targetTile.bottom = (y+1)*16;
				if(player->checkCollide(targetTile)){
					if(Map.returnCollideable(x,y) == 3){
						icy=true;
					}
					if(Map.returnCollideable(x,y) == 2){
						player->tookDamage(121);
					}
					if(player->checkCollideYprev(targetTile)){
						hcol++;
					}else if(player->checkCollideXprev(targetTile)){
						vcol++;
					}else{
						anyCollide=1;
					}
				}
			}
		}
	}
	if(icy){
		player->lessFriction(true);
	}else{
		player->lessFriction(false);
	}
	if(vcol){
		player->requestHover();
		player->setPos(player->getPosition().x, player->getPositionPrev().y);
	}
	if(hcol){
		player->setPos(player->getPositionPrev().x,player->getPosition().y);
		player->requestFullStop();
	}
	if((hcol != 0) && (vcol != 0) && (anyCollide)){
		player->setPos(player->getPositionPrev().x,player->getPositionPrev().y);
		player->requestHover();
	}
	detectEnemyCollision();
	detectPlayerCollisionwithPowerup();
	detectWeaponCollsionWithEnemy();
	detectEnemyCollisionWithTerrain();
	//detectWeaponCollsionWithPlayer();
	//detectWeaponCollsionWithTerrain();
}

void game::detectEnemyCollision(){
	std::vector<enemy*>::iterator iter;
	for(iter=enemies.begin();iter != enemies.end();iter++){
		if(player->checkCollide((*iter)->getBounds())){
			scorekeeper *Score = scorekeeper::getInstance();
			if((*iter)->getAI()==4){
				if((*iter)->getFacingRight()){
					player->tookDamage(8);
					Score->increaseHurt(8);
					player->knockback(1);
				}else{
					player->tookDamage(8);
					Score->increaseHurt(8);
					player->knockback(0);
				}
				player->reverse();
			}else{
				player->tookDamage(6);
				Score->increaseHurt(4);
				player->reverse();
			}
		}
	}	
}

void game::detectEnemyCollisionWithTerrain(){
	std::vector<enemy*>::iterator enemyIter;
	for(enemyIter=enemies.begin();enemyIter != enemies.end();enemyIter++){
		int vcol=0;
		int hcol=0;
		int anyCollide=0;
		t2DVector screenPos = Camera->updateSpritesOffset((*enemyIter)->getPos(),Map.getMapSize());
		int screenPosX = screenPos.x/(Fixed)tileSize;
		int screenPosY = screenPos.y/(Fixed)tileSize;
		int endScreenPosX = screenPosX + 16;
		int endScreenPosY = screenPosY + 12;
		for(int x=screenPosX;x<endScreenPosX;x++){
			for(int y=screenPosY;y<endScreenPosY;y++){
				if(Map.returnCollideable(x,y) == 5){
					player->tookDamage(125);//Death
				}
				if(Map.returnCollideable(x,y)==1 || Map.returnCollideable(x,y)==3){//collidable or icy
					BoundingBox targetTile;
		            targetTile.top = y*16;
				    targetTile.left = x*16;
					targetTile.right = (x+1)*16;
					targetTile.bottom = (y+1)*16;
					if((*enemyIter)->checkCollide(targetTile)){
						if((*enemyIter)->checkCollideYprev(targetTile)){
							hcol++;
						}else if((*enemyIter)->checkCollideXprev(targetTile)){
							vcol++;
						}else{
							anyCollide=1;
						}
					}
				}
			}
		}
		if(vcol){
			(*enemyIter)->stopVertical();
			(*enemyIter)->setPosition((*enemyIter)->getPos().x, (*enemyIter)->getPosPrev().y);
		}
		if(hcol){
			(*enemyIter)->setPosition((*enemyIter)->getPosPrev().x,(*enemyIter)->getPos().y);
			(*enemyIter)->stopHorizontal();
		}
		if((hcol != 0) && (vcol != 0) && (anyCollide)){
			(*enemyIter)->setPosition((*enemyIter)->getPosPrev().x,(*enemyIter)->getPosPrev().y);
			(*enemyIter)->stopVertical();
		}
	}
}

void game::detectPlayerCollisionwithPowerup(){
	for(int i=0;i<powerups.size();i++){
		if(player->checkCollide(powerups[i]->getBounds())){
			scorekeeper *Score = scorekeeper::getInstance();
			Score->increaseItems();
			powerups[i]->activatePowerup();
			
			delete powerups[i];
			powerups[i] = NULL;
			powerups.erase(powerups.begin() + i);
		}
	}
}

void game::detectWeaponCollsionWithEnemy(){
	//SES erase collision enemy
	std::vector<weapon*>::iterator weaponIter;
	std::vector<enemy*>::iterator enemyIter;
	for(weaponIter = projectiles.begin(); weaponIter != projectiles.end(); weaponIter++){
		if(!(*weaponIter)->getPlayerOwned()){
			if(player->checkCollide((*weaponIter)->getBounds())){
				player->tookDamage((*weaponIter)->getDamage());
				player->reverse();
				(*weaponIter)->markedForDeletion = true;
				scorekeeper* Score = scorekeeper::getInstance();
				Score->increaseHurt((*weaponIter)->getDamage());
			}
		}else{
			for(enemyIter=enemies.begin();enemyIter != enemies.end();enemyIter++){
				if((*enemyIter)->checkCollide((*weaponIter)->getBounds())){
					(*enemyIter)->applyDamage((*weaponIter)->getDamage());
					(*weaponIter)->markedForDeletion = true;
					scorekeeper* Score = scorekeeper::getInstance();
					Score->increaseShotsLanded();
					Score->increaseHits((*weaponIter)->getDamage());
				}
			}
		}
	}
}

void game::detectWeaponCollsionWithPlayer(){
}

void game::detectWeaponCollsionWithTerrain(){
}

void game::moveScreen(){
	t2DVector location = player->getPosition();
	t2DVector mapSize = Map.getMapSize();
	t2DVector spriteOffset = Camera->updateSpritesOffset(location,mapSize);

	Camera->setPos(spriteOffset.x,spriteOffset.y);
	player->setOffset(spriteOffset.x,spriteOffset.y);

	std::vector<enemy*>::iterator iterEnemy;
	for(iterEnemy = enemies.begin(); iterEnemy != enemies.end();iterEnemy++){
		(*iterEnemy)->setOffset(spriteOffset.x,spriteOffset.y);
	}

	std::vector<weapon*>::iterator iterWeapon;
	for(iterWeapon = projectiles.begin(); iterWeapon != projectiles.end(); iterWeapon++){
		(*iterWeapon)->setOffset(spriteOffset.x,spriteOffset.y);
	}
	
	std::vector<powerup*>::iterator iterPowerup;
	for(iterPowerup = powerups.begin();  iterPowerup != powerups.end(); iterPowerup++){
		(*iterPowerup)->setOffset(spriteOffset.x,spriteOffset.y);
	}
	BG3_CX = (int)location.x << 6;
}

void game::moveEnemy(){
	for(int i=0;i<enemies.size();i++){
		if(enemies[i]->isDead()){
				scorekeeper* Score = scorekeeper::getInstance();

			if(enemies[i]->getAI()==4){
				std::vector<weapon*>::iterator iterWeapon;
				for(iterWeapon = projectiles.begin(); iterWeapon != projectiles.end(); iterWeapon++){
					(*iterWeapon)->setHidden(true);
				}
				enemies[i]->setHidden(true);
				Score->increaseScore(5000);
				endGame();
			}else{
				Score->increaseScore(100);
			}
				Score->increaseKills();
				delete enemies[i];
				enemies[i] = NULL;
				enemies.erase(enemies.begin() + i);
				//i=0;
				
		}else{
			enemies[i]->enemyproximity(player->getPosition().x,player->getPosition().y);
			enemies[i]->updateEnemy(0,3);
		}
	}
}

void game::detectKeys(){
	if(keysDown() & KEY_START){
		paused = 1;
		pauseGame();
	}
}

void game::advanceLevel(){
	g_currentLevel++;
}

int game::getCurrentLevel(){
	return g_currentLevel;
}

void game::resetLevel(){
	while(!projectiles.empty()){
		delete projectiles[0];
		projectiles[0] = NULL;
		projectiles.erase(projectiles.begin());
	}
	while(!enemies.empty()){
		delete enemies[0];
		enemies[0] = NULL;
		enemies.erase(enemies.begin());
	}
	while(!powerups.empty()){
		delete powerups[0];
		powerups[0] = NULL;
		powerups.erase(powerups.begin());
	}
	//projectiles.clear();
	//enemies.clear();
	//powerups.clear();
	player->reset();
	startLevel(g_currentLevel);
}

void game::clearLevel(){
	while(!projectiles.empty()){
		delete projectiles[0];
		projectiles[0] = NULL;
		projectiles.erase(projectiles.begin());
	}
	while(!enemies.empty()){
		delete enemies[0];
		enemies[0] = NULL;
		enemies.erase(enemies.begin());
	}
	while(!powerups.empty()){
		delete powerups[0];
		powerups[0] = NULL;
		powerups.erase(powerups.begin());
	}
	//projectiles.clear();
	//enemies.clear();
	//powerups.clear();
	player->reset();
}

void game::cutScene(int level){
	bool inCutScene = true;
	bool needToPressA = true;
	if(level == 1){
		Map.displaySubScreen(phoneBackgroundBitmap,phoneBackgroundBitmapLen);
		consoleClear();
		printf("\n\n\n\n\n\n\n\n\n\n\n");
		printf("       LEVEL ONE PASSWORD:  \n");
		printf("           657868826987 \n");
				while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}									  //no text past here
		needToPressA=true;
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		//                line up with pic
		//                                  no letters beyond here
		printf("    Our story begins with our\n");
		printf("    young genius starting\n");
		printf("    off in his summer \n");
		printf("    job as an Orientation \n");
		printf("    Assistant for freshmen\n");
		printf("    and transfer students\n");
		printf("    at the University of\n");
		printf("    Kansas. During one\n");
		printf("    of his sessions he\n");
		printf("    meets a new transfer \n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}									  //no text past here
		needToPressA=true;
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("    student who completely\n");
		printf("    stuns him, but of course\n");
		printf("    she is out his league \n");
		printf("    like always. Especially  \n");
		printf("    once school starts up he \n");
		printf("    will be way too busy with \n");
		printf("    homework assignments and \n");
		printf("    projects for all of his  \n");
		printf("    engineering classes.There\n");
		printf("    isnt a chance but if only \n");
		printf("    our genius could find a \n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("    wayto get her attention? \n");
		printf("    The mysterious new girl \n");
		printf("    comes up to him and asks \n");
		printf("    for his help in finding \n"); 
		printf("    out where she can get her \n");
		printf("    KU card for campus. As  \n");
		printf("    any awkward engineer, he \n");
		printf("    stammers out a reply;must \n");
		printf("    be since he is not used \n");
		printf("    to speaking to the opp-\n");
		printf("    osite sex.He tells her \n");
				while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("    if she has any other que-\n");
		printf("    stions that this is his \n");
		printf("    number and she can simply \n");
		printf("    call him at her conven-\n");
		printf("    ience; Christina is than-\n");
		printf("    kful and asks if she will \n");
		printf("    see him at the fireworks \n");
		printf("    show for all the new \n");
		printf("    students. Complete the \n");
		printf("    level in order to attend \n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("    the show, and collect \n");
		printf("    fireworks along the way \n");
		printf("    to make the night more \n");
		printf("    memorable for your new \n");
		printf("    love interest. \n");
	}else if(level == 2){
		Map.displaySubScreen(phoneBackgroundBitmap,phoneBackgroundBitmapLen);
		consoleClear();
		printf("\n\n\n\n\n\n\n\n\n\n\n");
		printf("       LEVEL TWO PASSWORD:  \n");
		printf("            68826965 \n");
				while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}									  //no text past here
		needToPressA=true;
		Map.displaySubScreen(cutScene1Bitmap,cutScene1BitmapLen);
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08: Hey!\n");  
		printf("          Its Christina, \n"); 
		printf("          we met at orien-\n");
		printf("          tation remember?\n\n\n");
		printf("    Born2Code: Oh yea, \n");
		printf("      I think you are \n");
		printf("      in my COMS class?\n");

		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08: Oh \n");  
		printf("          its such a large\n");
		printf("          class, I didnt see \n");  
		printf("          u. So are u a COMS\n"); 
		printf("          major too then?\n\n\n");
		printf("    Born2Code: haha no, \n");
		printf("     Im an engineering \n"); 
		printf("     student.\n");
			while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08:Cool, \n");  
		printf("          so do you like  \n");
		printf("          make engines as\n");
		printf("          an engineer?\n\n");
		printf("    Born2Code: umm no, \n");
		printf("     not all engineers \n");
		printf("     make engines lol. \n");
		printf("     Never heard that \n");
		printf("     before, so do you \n");
		printf("     like communicating \n");
		printf("     as a COMS major? \n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08:Sure \n");
		printf("          do. Haha, you are\n");
		printf("          too funny.... I \n");
		printf("          think u r cute!\n\n\n");
		printf("    Born2Code: ....... \n");
		printf("     Seriously....me?\n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08:Yup, \n");
		printf("          besides you are \n");
		printf("          sweet. I know u \n");
		printf("          helped with part\n");
		printf("    of the fireworks show, \n");
		printf("    I liked it. Maybe\n");
		printf("    Ill see you at the\n");
		printf("    Halloween party?\n\n\n");
		printf("    Born2Code: uh, sure!\n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		Map.displaySubScreen(phoneBackgroundBitmap,phoneBackgroundBitmapLen);
		printf("\n\n\n\n\n\n\n\n");
		printf("    Being yourself wont count\n");
		printf("    so try not coming dressed\n");
		printf("    as a nerd. Good thing you\n");
		printf("    have a part time job. \n");
		printf("    Collect leaves along the\n");
		printf("    way in order to make some\n");
		printf("    extra money to buy an \n");
		printf("    actual costume for the\n");
		printf("    Halloween party.\n");
	}else if(level == 3){
		Map.displaySubScreen(phoneBackgroundBitmap,phoneBackgroundBitmapLen);
		consoleClear();
		printf("\n\n\n\n\n\n\n\n\n\n\n");
		printf("       LEVEL THREE PASSWORD:  \n");
		printf("            7589766982 \n");
				while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}									  //no text past here
		needToPressA=true;
		Map.displaySubScreen(cutScene1Bitmap,cutScene1BitmapLen);
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08: Hey! \n");
		printf("          It was nice seeing\n");
		printf("          you at the Hallo-\n");
		printf("          ween party. almost\n");
		printf("    didnt recognize\n");
		printf("    you with your \n");
		printf("    full out MegaMan\n");
		printf("    costume.\n\n");
		printf("    Born2Code: Ha, Im  \n");
		printf("     suprised you even \n");
		printf("     recognized me. \n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08: Lol. \n");
		printf("          I was mening to   \n");
		printf("          ask you, would u \n");
		printf("          want 2 go to my\n");
		printf("          sorority's semi-\n");
		printf("          formal?\n\n");
		printf("    Born2Code: Why r u   \n");
		printf("     asking me? Havent\n");
		printf("     u met a bunch of\n");
		printf("     other guys?\n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08: Haha \n");
		printf("          I have, i just    \n");
		printf("          knew u wouldnt be\n");
		printf("          a jerk. it can \n");
		printf("    just be friends if    \n");
		printf("    thats better.\n\n");
		printf("    Born2Code: sry for   \n");
		printf("     being a jerk then\n");
		printf("     i just thought  \n");
		printf("     u were playing\n");
		printf("     a joke on me. \n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08: o i c.\n");
		printf("          Now I know you like\n");
		printf("          MegaMan but you \n");
		printf("          cant come dressed\n");
		printf("    like that again. That   \n");
		printf("    would be embarassing. \n\n"); 
		printf("    Born2Code: Lol dont   \n");
		printf("     worry I will try \n");
		printf("     to find something  \n");
		printf("     else to wear \n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08:Great!\n");
		printf("          ttyl then.\n\n\n\n\n\n");
		printf("      Born2Code: Bye. \n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		Map.displaySubScreen(phoneBackgroundBitmap,phoneBackgroundBitmapLen);
		printf("\n\n\n\n\n\n\n\n");
		printf("    Its time to really \n");
		printf("    impress your date.   \n");
		printf("    Collect snow figurines\n");
		printf("    to bring as gifts to  \n");
		printf("    the Mistletoe Semi-   \n");
		printf("    Formal, but be careful\n");
		printf("    to not slip and break\n");
		printf("    them.             \n");;
	}else if(level == 4){
		Map.displaySubScreen(phoneBackgroundBitmap,phoneBackgroundBitmapLen);
		consoleClear();
		printf("\n\n\n\n\n\n\n\n\n\n\n");
		printf("       LEVEL FOUR PASSWORD:  \n");
		printf("         6869677383738669 \n");
				while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}									  //no text past here
		needToPressA=true;
		Map.displaySubScreen(cutScene1Bitmap,cutScene1BitmapLen);
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08:Hey\n");
		printf("          Kieran.\n\n\n\n");
		printf("    Born2Code: Hey \n");
		printf("     Christina, I know \n");
		printf("     I kinda went under\n");
		printf("     the radar during\n");
		printf("     finals week and Im\n");
		printf("     sry 4 not calling u back. \n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08:Its\n");
		printf("          okay.....\n\n\n\n");
		printf("    Born2Code: I \n");
		printf("     will make it up   \n");
		printf("     to you this quar-\n");
		printf("     ter if you let me \n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08:Idk\n");
		printf("          u dont seem   \n");
		printf("          like u would have\n");
		printf("          time to actually\n");
		printf("          date as it is.\n\n");
		printf("    Born2Code: Plz \n");
		printf("     I promise I will \n");
		printf("     find the time...   \n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		printf("\n\n\n\n\n\n\n");
		printf("         UrPrInCeSs08:Okay\n");
		printf("          I guess......\n\n\n\n\n");
		printf("    Born2Code: I \n");
		printf("     wont let you down \n");
		while(needToPressA){
			scanKeys();
			if(keysDown() & KEY_A){
				needToPressA=false;
			}

		}
		needToPressA=true;					   //no text past here
		consoleClear();
		Map.displaySubScreen(phoneBackgroundBitmap,phoneBackgroundBitmapLen);
		printf("\n\n\n\n\n\n\n\n\n");
		printf("    Cmon now, collect  \n");
		printf("    various flowers to   \n");
		printf("    win her back; you are \n");
		printf("    so close to finding \n");
		printf("    love as an engineer.  \n");
	}
	while(inCutScene){
		scanKeys();
		if(keysDown() & KEY_A){
			inCutScene = false;
			Map.displaySubScreen(phoneBackgroundBitmap,phoneBackgroundBitmapLen);
		}

	}
}

void game::createEnemies(int level){
	int enemyOneHealth = 30;
	int enemyTwoHealth = 15;
	int enemyThreeHealth = 15;
	if(level == 1){
		makeEnemy(63.0, 26.0, enemyOneHealth, 1);
		makeEnemy(125.0, 16.0, enemyOneHealth, 1);
		makeEnemy(177.0, 4.0, enemyOneHealth, 1);
		makeEnemy(181.0, 4.0, enemyOneHealth, 1);
		makeEnemy(187.0, 4.0, enemyOneHealth, 1);
		makeEnemy(210.0, 22.0, enemyOneHealth, 1);
		makeEnemy(290.0, 18.0, enemyOneHealth, 1);
		makeEnemy(323.0, 26.0, enemyOneHealth, 1);
		makeEnemy(382.0, 22.0, enemyOneHealth, 1);
		makeEnemy(121.0, 13.0, enemyTwoHealth, 2);
		makeEnemy(312.0, 22.0, enemyTwoHealth, 2);
		makeEnemy(96.0, 22.0, enemyThreeHealth, 3);
		makeEnemy(396.0, 9.0, enemyThreeHealth, 3);
	}else if(level == 2){
		makeEnemy(22.0, 26.0, enemyOneHealth, 1);
		makeEnemy(58.0, 26.0, enemyOneHealth, 1);
		makeEnemy(116.0, 19.0, enemyOneHealth, 1);
		makeEnemy(119.0, 7.0, enemyOneHealth, 1);
		makeEnemy(119.0, 40.0, enemyOneHealth, 1);
		makeEnemy(174.0, 24.0, enemyOneHealth, 1);
		makeEnemy(211.0, 12.0, enemyOneHealth, 1);
		makeEnemy(244.0, 29.0, enemyOneHealth, 1);
		makeEnemy(246.0, 29.0, enemyOneHealth, 1);
		makeEnemy(261.0, 29.0, enemyOneHealth, 1);
		makeEnemy(284.0, 29.0, enemyOneHealth, 1);
		makeEnemy(292.0, 27.0, enemyOneHealth, 1);
		makeEnemy(294.0, 25.0, enemyOneHealth, 1);
		makeEnemy(348.0, 25.0, enemyOneHealth, 1);
		makeEnemy(337.0, 29.0, enemyOneHealth, 1);
		makeEnemy(359.0, 29.0, enemyOneHealth, 1);
		makeEnemy(391.0, 42.0, enemyOneHealth, 1);
		makeEnemy(75.0, 24.0, enemyTwoHealth, 2);
		makeEnemy(184.0, 14.0, enemyTwoHealth, 2);
		makeEnemy(304.0, 17.0, enemyTwoHealth, 2);
		makeEnemy(30.0, 24.0, enemyThreeHealth, 3);
		makeEnemy(253.0, 28.0, enemyThreeHealth, 3);
		makeEnemy(330.0, 21.0, enemyThreeHealth, 3);
	}else if(level == 3){
		printf("enemies %i powerups %i\n",enemies.size(),powerups.size());
		makeEnemy(23.0, 26.0, enemyOneHealth, 1);
		makeEnemy(40.0, 48.0, enemyOneHealth, 1);
		makeEnemy(85.0, 55.0, enemyOneHealth, 1);
		makeEnemy(58.0, 55.0, enemyOneHealth, 1);
		makeEnemy(172.0, 34.0, enemyOneHealth, 1);
		makeEnemy(172.0, 38.0, enemyOneHealth, 1);
		makeEnemy(184.0, 38.0, enemyOneHealth, 1);
		makeEnemy(243.0, 25.0, enemyOneHealth, 1);
		makeEnemy(238.0, 25.0, enemyOneHealth, 1);
		makeEnemy(247.0, 25.0, enemyOneHealth, 1);
		makeEnemy(252.0, 25.0, enemyOneHealth, 1);
		makeEnemy(266.0, 33.0, enemyOneHealth, 1);
		makeEnemy(271.0, 23.0, enemyOneHealth, 1);
		makeEnemy(292.0, 33.0, enemyOneHealth, 1);
		makeEnemy(298.0, 33.0, enemyOneHealth, 1);
		makeEnemy(318.0, 30.0, enemyOneHealth, 1);
		makeEnemy(345.0, 24.0, enemyOneHealth, 1);
		makeEnemy(378.0, 24.0, enemyOneHealth, 1);
		makeEnemy(385.0, 22.0, enemyOneHealth, 1);
		makeEnemy(387.0, 20.0, enemyOneHealth, 1);
		makeEnemy(389.0, 18.0, enemyOneHealth, 1);
		makeEnemy(71.0, 37.0, enemyTwoHealth, 2);
		makeEnemy(209.0, 24.0, enemyTwoHealth, 2);
		makeEnemy(320.0, 21.0, enemyTwoHealth, 2);
		makeEnemy(359.0, 20.0, enemyTwoHealth, 2);
		makeEnemy(113.0, 43.0, enemyThreeHealth, 3);
		makeEnemy(371.0, 20.0, enemyThreeHealth, 3);

	}else if(level == 4){
		makeEnemy(16.0, 25.0, enemyOneHealth, 1);
		makeEnemy(71.0, 20.0, enemyOneHealth, 1);
		makeEnemy(77.0, 20.0, enemyOneHealth, 1);
		makeEnemy(71.0, 16.0, enemyOneHealth, 1);
		makeEnemy(77.0, 16.0, enemyOneHealth, 1);
		makeEnemy(132.0, 55.0, enemyOneHealth, 1);
		makeEnemy(141.0, 55.0, enemyOneHealth, 1);
		makeEnemy(167.0, 54.0, enemyOneHealth, 1);
		makeEnemy(177.0, 11.0, enemyOneHealth, 1);
		makeEnemy(198.0, 36.0, enemyOneHealth, 1);
		makeEnemy(211.0, 11.0, enemyOneHealth, 1);
		makeEnemy(284.0, 46.0, enemyOneHealth, 1);
		makeEnemy(273.0, 30.0, enemyOneHealth, 1);
		makeEnemy(310.0, 36.0, enemyOneHealth, 1);
		makeEnemy(322.0, 34.0, enemyOneHealth, 1);
		makeEnemy(330.0, 34.0, enemyOneHealth, 1);
		makeEnemy(322.0, 39.0, enemyOneHealth, 1);
		makeEnemy(330.0, 39.0, enemyOneHealth, 1);
		makeEnemy(372.0, 26.0, enemyOneHealth, 1);
		makeEnemy(381.0, 26.0, enemyOneHealth, 1);
		makeEnemy(343.0, 29.0, enemyTwoHealth, 2);
		makeEnemy(361.0, 22.0, enemyTwoHealth, 2);
		makeEnemy(210.0, 31.0, enemyTwoHealth, 2);
		makeEnemy(102.0, 16.0, enemyTwoHealth, 2);
		makeEnemy(33.0, 22.0, enemyTwoHealth, 2);
		makeEnemy(374.0, 20.0, enemyTwoHealth, 2);
		makeEnemy(386.0, 20.0, enemyTwoHealth, 2);
		makeEnemy(304.0, 36.0, enemyThreeHealth, 3);
		makeEnemy(246.0, 27.0, enemyThreeHealth, 3);
		makeEnemy(181.0, 23.0, enemyThreeHealth, 3);
		makeEnemy(395.0,50.0,350,4);
	}
}

void game::makeEnemy(tFloat posX, tFloat posY, int health, int AItype){
	if(AItype==1){
		enemy *temp = new enemy;
		temp->createEnemy(enemy1Tiles,enemy1Pal);
		temp->setHealth(health);
		temp->setPosition(posX*16.0,posY*16.0);
		temp->setAI(AItype);
		enemies.push_back(temp);
		temp->setHidden(false);
	}else if(AItype==2){
		enemy *temp = new enemy;
		temp->createEnemy(enemy2Tiles,enemy2Pal);
		temp->setHealth(health);
		temp->setPosition(posX*16.0,posY*16.0);
		temp->setAI(AItype);
		enemies.push_back(temp);
	}else if(AItype == 3){
		enemy *temp = new enemy;
		temp->createEnemy(enemy2Tiles,enemy2Pal);
		temp->setHealth(health);
		temp->setPosition(posX*16.0,posY*16.0);
		temp->setAI(AItype);
		enemies.push_back(temp);
	}else if(AItype == 4){
		enemy *temp = new enemy;
		temp->createEnemy(BossTiles,BossPal);
		temp->setHealth(health);
		temp->setPosition(posX*16.0,posY*16.0);
		temp->setAI(AItype);
		enemies.push_back(temp);
	}
	scorekeeper* Score = scorekeeper::getInstance();
	Score->increaseEnemyCount();
	
}
void game::createPowerups(int level){
	if(level==1){
		makePowerup(394.0, 22.0, 4);
		makePowerup(77.0, 15.0, 3);
		makePowerup(51.0, 52.0, 3);
		makePowerup(67.0, 36.0, 3);
		makePowerup(148.0, 11.0, 3);
		makePowerup(169.0, 1.0, 3);
		makePowerup(191.0, 1.0, 3);
		makePowerup(205.0, 6.0, 3);
		makePowerup(256.0, 16.0, 3);
		makePowerup(318.0, 23.0, 3);
		makePowerup(390.0, 8.0, 3);
		makePowerup(58.0, 9.0, 2);
		makePowerup(256.0, 22.0, 2);
		makePowerup(134.0, 13.0, 1);
		makePowerup(290.0, 15.0, 1);
		makePowerup(319.0, 52.0, 22);
		makePowerup(8.0, 4.0, 17);
		makePowerup(147.0, 27.0, 18);
		makePowerup(289.0, 24.0, 19);
		makePowerup(386.0, 21.0, 20);
		makePowerup(73.0, 30.0, 21);
	}else if(level == 2){
		makePowerup(395.0, 46.0, 4);
		makePowerup(84.0, 27.0, 3);
		makePowerup(141.0, 19.0, 3);
		makePowerup(139.0, 5.0, 3);
		makePowerup(139.0, 6.0, 3);
		makePowerup(222.0, 14.0, 3);
		makePowerup(282.0, 52.0, 3);
		makePowerup(284.0, 52.0, 3);
		makePowerup(286.0, 52.0, 3);
		makePowerup(344.0, 43.0, 3);
		makePowerup(344.0, 45.0, 3);
		makePowerup(344.0, 47.0, 3);
		makePowerup(364.0, 43.0, 3);
		makePowerup(240.0, 53.0, 2);
		makePowerup(155.0, 34.0, 2);
		makePowerup(24.0, 26.0, 1);
		makePowerup(231.0, 52.0, 1);
		makePowerup(320.0, 28.0, 1);
		makePowerup(31.0, 37.0, 12);
		makePowerup(134.0, 40.0, 13);
		makePowerup(263.0, 53.0, 14);
		makePowerup(151.0, 26.0, 15);
		makePowerup(100.0, 7.0, 16);
		makePowerup(221.0, 54.0, 22);
	}else if(level == 3){
		makePowerup(397.0, 48.0, 4);
		makePowerup(22.0, 24.0, 3);
		makePowerup(24.0, 24.0, 3);
		makePowerup(73.0, 54.0, 3);
		makePowerup(60.0, 54.0, 3);
		makePowerup(135.0, 38.0, 3);
		makePowerup(161.0, 31.0, 3);
		makePowerup(202.0, 27.0, 3);
		makePowerup(210.0, 25.0, 3);
		makePowerup(218.0, 23.0, 3);
		makePowerup(226.0, 21.0, 3);
		makePowerup(266.0, 25.0, 3);
		makePowerup(284.0, 24.0, 3);
		makePowerup(349.0, 25.0, 3);
		makePowerup(359.0, 25.0, 3);
		makePowerup(369.0, 25.0, 3);
		makePowerup(172.0, 34.0, 2);
		makePowerup(266.0, 22.0, 2);
		makePowerup(394.0, 35.0, 1);
		makePowerup(148.0, 38.0, 1);
		makePowerup(142.0, 45.0, 11);
		makePowerup(214.0, 42.0, 11);
		makePowerup(88.0, 55.0, 11);
		makePowerup(277.0, 23.0, 11);
		makePowerup(98.0, 28.0, 11);
		makePowerup(351.0, 54.0, 22);
	}else if(level == 4){
		makePowerup(398.0, 27.0, 5);
		makePowerup(29.0, 25.0, 3);
		makePowerup(71.0, 17.0, 3);
		makePowerup(127.0, 39.0, 3);
		makePowerup(143.0, 35.0, 3);
		makePowerup(159.0, 31.0, 3);
		makePowerup(169.0, 57.0, 3);
		makePowerup(170.0, 23.0, 3);
		makePowerup(170.0, 17.0, 3);
		makePowerup(188.0, 12.0, 3);
		makePowerup(259.0, 29.0, 3);
		makePowerup(261.0, 29.0, 3);
		makePowerup(346.0, 34.0, 3);
		makePowerup(355.0, 30.0, 3);
		makePowerup(364.0, 27.0, 3);
		makePowerup(371.0, 26.0, 2);
		makePowerup(78.0, 21.0, 2);
		makePowerup(373.0, 26.0, 1);
		makePowerup(78.0, 16.0, 1);
		makePowerup(320.0, 40.0, 6);
		makePowerup(257.0, 47.0, 7);
		makePowerup(178.0, 12.0, 8);
		makePowerup(160.0, 57.0, 9);
		makePowerup(68.0, 25.0, 10);
		makePowerup(194.0, 12.0, 22);

	}
}

void game::makePowerup(tFloat posX,tFloat posY,int type){
	/*  What sprite i is assigned to.
	1 - Speedup
	2 - Health
	3 - Ammo
	4 - Next Level
	5 - End Game
	6->10 - Flowers
	11 - Ice Sculpture
	12->16 - Leaves
	17->21 - Rockets
	22 - Diamond
	*/
	powerup *temp = new powerup;
	temp->assignSprite();
	temp->setPos(posX*16.0,posY*16.0);
	temp->setType(type);
	powerups.push_back(temp);
	scorekeeper* Score = scorekeeper::getInstance();
	Score->increaseItemCount();
}

void game::detectOffscreenWeapons(){

	//SES delete offscreens
	if(!projectiles.empty()){

		for (int i = 0; i < projectiles.size(); i++) {
			t2DVector weaponPos = projectiles[i]->getPos();
			t2DVector cameraPos = Camera->getPos();

			if((weaponPos.x - cameraPos.x) < -32.0){
				projectiles[i]->markedForDeletion = true;
				//printf("marked for deletion ln 477\n");
			}else if((weaponPos.x-cameraPos.x) > (SCREEN_WIDTH+32.0)){
				projectiles[i]->markedForDeletion = true;
				//printf("marked for deletion ln 482\n");
			}else if((weaponPos.y-cameraPos.y) < -32.0){
				projectiles[i]->markedForDeletion = true;
				//printf("marked for deletion ln 486\n");
			}else if((weaponPos.y-cameraPos.y) > SCREEN_HEIGHT+32.0){
				projectiles[i]->markedForDeletion = true;
				//printf("marked for deletion ln 491\n");
			}

			if (projectiles[i]->markedForDeletion) {
				//printf("projectile deleted\n");
				
				delete projectiles[i];
				projectiles[i] = NULL;
				projectiles.erase(projectiles.begin() + i);
				
			}
		}
	}
}

void game::pauseGame(){
	while(paused){
		scanKeys();
		if(keysDown() & KEY_START){
			paused = 0;
		}else if(keysDown() & KEY_SELECT){
			paused = 0;
			resetLevel();
		}else if((keysHeld() & KEY_L) && (keysHeld() & KEY_R)){
			//if(player->getPosition().x > 3000.0){
			//	player->setPos(0.0,0.0);
			//}else{
				player->setPos(398.0*16.0, 0.0);
			//}
		}
	}
}

void game::deadLeadsToReset(){
	bool resetQuestion = true;
	dmaCopyHalfWords(DmaChannel, resetYesNoBitmap, (uint16 *)BG_BMP_RAM(8),resetYesNoBitmapLen);
	BG3_CX = 0;
	videoSetMode(MODE_4_2D |
			 //DISPLAY_BG0_ACTIVE |
			 DISPLAY_BG2_ACTIVE |
			 DISPLAY_BG3_ACTIVE |
			 DISPLAY_SPR_ACTIVE |
			 DISPLAY_SPR_1D);
	while(resetQuestion){
		scanKeys();
		if(keysDown() & KEY_A){
			resetQuestion=false;
			videoSetMode(MODE_4_2D |
			 DISPLAY_BG0_ACTIVE |
			 DISPLAY_BG2_ACTIVE |
			 DISPLAY_BG3_ACTIVE |
			 DISPLAY_SPR_ACTIVE |
			 DISPLAY_SPR_1D);
			 //BG3_CX = (int)location.x << 6;
		}else if(keysDown() & KEY_B){
			dmaCopyHalfWords(DmaChannel,byeThenBitmap,(uint16 *)BG_BMP_RAM(8),byeThenBitmapLen);
			while(resetQuestion){
			}
		}
		swiWaitForVBlank();
		lnSpritesUpdate();
	}
	resetLevel();
}

void game::spawnEnemy(){
}

void game::endGame(){
	player->setHidden(true);
	dmaCopyHalfWords(DmaChannel, endGameBitmap, (uint16 *)BG_BMP_RAM(8),endGameBitmapLen);
	BG3_CX = 0;
	videoSetMode(MODE_4_2D |
			 //DISPLAY_BG0_ACTIVE |
			 DISPLAY_BG2_ACTIVE |
			 DISPLAY_BG3_ACTIVE |
			 DISPLAY_SPR_ACTIVE |
			 DISPLAY_SPR_1D);
	swiWaitForVBlank();
	lnSpritesUpdate();	
	scorekeeper *Score = scorekeeper::getInstance();
	Score->gameReport();

}